home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libgutil / abekas.c next >
C/C++ Source or Header  |  1994-08-01  |  5KB  |  242 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *    abekas- 
  19.  *        Support for digital video conversions.
  20.  *
  21.  *                     Paul Haeberli - 1993
  22.  *    exports
  23.  *
  24.     void zoom720to640(ibuf,obuf)
  25.     void zoom640to720(ibuf,obuf)
  26.     void YUVdither(doit)
  27.     void UYVYtoRGB(ap,rp,gp,bp)
  28.     void RGBtoUYVY(rp,gp,bp,ap) 
  29.  *
  30.  */
  31. #include "stdio.h"
  32. #include "math.h"
  33.  
  34. #define NGROUPS        (720/9)
  35. #define    XSIZE        (720)
  36.  
  37. static int dodither;
  38.  
  39. void zoom720to640(ibuf,obuf)
  40. short *ibuf,  *obuf;
  41. {
  42.      int n;
  43.  
  44.      for(n=0; n<NGROUPS; n++) {
  45.      obuf[0] = ((8*ibuf[0])+(1*ibuf[1])+4)/9;
  46.      obuf[1] = ((7*ibuf[1])+(2*ibuf[2])+4)/9;
  47.      obuf[2] = ((6*ibuf[2])+(3*ibuf[3])+4)/9;
  48.      obuf[3] = ((5*ibuf[3])+(4*ibuf[4])+4)/9;
  49.      obuf[4] = ((4*ibuf[5])+(5*ibuf[5])+4)/9;
  50.      obuf[5] = ((3*ibuf[4])+(6*ibuf[6])+4)/9;
  51.      obuf[6] = ((2*ibuf[5])+(7*ibuf[7])+4)/9;
  52.      obuf[7] = ((1*ibuf[6])+(8*ibuf[8])+4)/9;
  53.      obuf += 8;
  54.      ibuf += 9;
  55.      }
  56. }
  57.  
  58. void zoom640to720(ibuf,obuf)
  59. short *ibuf,  *obuf;
  60. {
  61.      int n;
  62.  
  63.      for(n=0; n<NGROUPS; n++) {
  64.      obuf[0] = ((8*ibuf[0])+(0*ibuf[0])+4)/8;
  65.      obuf[1] = ((7*ibuf[1])+(1*ibuf[0])+4)/8;
  66.      obuf[2] = ((6*ibuf[2])+(2*ibuf[1])+4)/8;
  67.      obuf[3] = ((5*ibuf[3])+(3*ibuf[2])+4)/8;
  68.      obuf[4] = ((4*ibuf[4])+(4*ibuf[3])+4)/8;
  69.      obuf[5] = ((3*ibuf[5])+(5*ibuf[4])+4)/8;
  70.      obuf[6] = ((2*ibuf[6])+(6*ibuf[5])+4)/8;
  71.      obuf[7] = ((1*ibuf[7])+(7*ibuf[6])+4)/8;
  72.      obuf[8] = ((0*ibuf[7])+(8*ibuf[7])+4)/8;
  73.      obuf += 9;
  74.      ibuf += 8;
  75.      }
  76. }
  77.  
  78. #define LIMIT(r,x) {             \
  79.     r = x;                \
  80.     if(r >  0x00ffffff) r = 0x00ffffff; \
  81.     if(r <= 0x00000000) r = 0;         \
  82. }
  83.  
  84. void YUVdither(doit)
  85. int doit;
  86. {
  87.     dodither = doit;
  88. }
  89.  
  90. /*
  91.  *     256*256*255/219 is 76309.04109589 this is "1" for y
  92.  *     256*256*255/223 is 74940.26905830 this is "1" for u and v
  93.  *
  94.  *    The inverse matrix is:
  95.  *
  96.  *    1.000000         0.000000         1.402581        
  97.  *    1.000000        -0.344369        -0.714407       
  98.  *    1.000000         1.773043        -0.000000       
  99.  *
  100.  */
  101. void UYVYtoRGB(ap,rp,gp,bp)
  102. unsigned char *ap;
  103. short *rp, *gp, *bp;
  104. {
  105.     int j; 
  106.     long y, u, v, y1, r, g, b;
  107.     long qr, qg, qb;
  108.  
  109.     if(dodither) {
  110.     qr = random()%0x4000;
  111.     qg = random()%0x4000;
  112.     qb = random()%0x4000;
  113.     }
  114.     for(j=0; j<(XSIZE/2); j++) {
  115.     u = ap[0];
  116.     u -= 128;
  117.     y = ap[1];
  118.     y -= 16;
  119.     if(y<0) y = 0;
  120.  
  121.     v = ap[2];
  122.     v -= 128;
  123.     y1 = ap[3];
  124.     y1 -= 16;
  125.     if(y1<0) y1 = 0;
  126.  
  127.     ap+=4;
  128.  
  129.     y *= 76309;    
  130.     r  =    y  +            105110*v;
  131.     g  =    y  + -25807*u + -53538*v;
  132.     b  =    y  + 132872*u;
  133.  
  134.       if(dodither) {
  135.         LIMIT(qr,r+(qr & 0xffff));
  136.         LIMIT(qg,g+(qg & 0xffff));
  137.         LIMIT(qb,b+(qb & 0xffff));
  138.      } else {
  139.         LIMIT(qr,r);
  140.         LIMIT(qg,g);
  141.         LIMIT(qb,b);
  142.     }
  143.  
  144.     *rp++ = qr>>16;
  145.     *gp++ = qg>>16;
  146.     *bp++ = qb>>16;
  147.  
  148.     y1 *= 76309;
  149.     r  =    y1 +            105110*v;
  150.     g  =    y1 + -25807*u + -53538*v;
  151.     b  =    y1 + 132872*u;
  152.  
  153.       if(dodither) {
  154.         LIMIT(qr,r+(qr & 0xffff));
  155.         LIMIT(qg,g+(qg & 0xffff));
  156.         LIMIT(qb,b+(qb & 0xffff));
  157.     } else {
  158.         LIMIT(qr,r);
  159.         LIMIT(qg,g);
  160.         LIMIT(qb,b);
  161.     }
  162.  
  163.     *rp++ = qr>>16;
  164.     *gp++ = qg>>16;
  165.     *bp++ = qb>>16;
  166.     }
  167. }
  168.  
  169. /*
  170.  *     256*256*219/255 is 56283.85882352 this is "1" for y
  171.  *     256*256*223/255 is 57311.87450980 this is "1" for u and v
  172.  *
  173.  *    The forward matrix is:
  174.  *
  175.  *     0.2990             0.5870             0.1140
  176.  *    -0.1686            -0.3311             0.4997
  177.  *     0.4998            -0.4185            -0.0813
  178.  *
  179.  */
  180. void RGBtoUYVY(rp,gp,bp,ap) 
  181. unsigned short *rp, *gp, *bp;
  182. unsigned char *ap;
  183.     int i, r, g, b;
  184.     long y1, y2, u, v, u1, u2, v1, v2;
  185.  
  186.     if(dodither) { 
  187.     y1 = random()%0x4000;
  188.     y2 = random()%0x4000;
  189.     } else {
  190.     y1 = 0;
  191.     y2 = 0;
  192.     }
  193.     for(i = XSIZE/2; i>0; i--) { 
  194.  
  195. /* first pixel gives Y and 0.5 of chroma */ 
  196.     r = *rp++;
  197.     g = *gp++;
  198.     b = *bp++;
  199.  
  200.     y1  =    16829*r +  33039*g +  6416*b;
  201.     u1  =    -4831*r +  -9488*g + 14319*b;
  202.     v1  =    14322*r + -11992*g + -2330*b;
  203.     if(dodither) y1 += (y2&0xffff);
  204.  
  205. /* second pixel gives Y and 0.5 of chroma */ 
  206.     r = *rp++;
  207.     g = *gp++;
  208.     b = *bp++;
  209.  
  210.     y2  =    16829*r +  33039*g +  6416*b;
  211.     u2  =    -4831*r +  -9488*g + 14319*b;
  212.     v2  =    14322*r + -11992*g + -2330*b;
  213.     if(dodither) y2 += (y1&0xffff);
  214.  
  215. /* average the chroma */
  216.     u = u1 + u2;
  217.     v = v1 + v2;
  218.  
  219. /* round the chroma */
  220.     u1 = (u+0x008000)>>16;
  221.     v1 = (v+0x008000)>>16;
  222.  
  223. /* limit the chroma */
  224.     if(u1<-112) u1 = -112;
  225.     if(u1>111) u1 = 111;
  226.     if(v1<-112) v1 = -112;
  227.     if(v1>111) v1 = 111;
  228.  
  229. /* limit the lum */
  230.        if(y1>0x00dbffff) y1=0x00dbffff;
  231.        if(y2>0x00dbffff) y2=0x00dbffff;
  232.  
  233. /* save the results */
  234.     ap[0] = u1 +128;
  235.     ap[1] = (y1>>16) + 16;
  236.     ap[2] = v1 +128;
  237.     ap[3] = (y2>>16) + 16;
  238.     ap += 4;
  239.     }
  240.